<?php

/*
 *	Framework namespace
 */
namespace Nano
{
	/*
	 *	File system class
	 */
	class Filesystem
	{
		/*
		 *	Change group owner of file
		 *
		 *	@param	string	Path to file
		 *	@param	mixed	Group name or id
		 *	@param	boolean	Clear cache for next usage?	[optional]
		 *	@return	boolean
		 *	
		 *	@static
		 */
		static public function chgrp($file, $group, $cache = true)
		{
			$result = chgroup($file, $group);
			
			if(!$cache)
			{
				clearstatcache();
			}
			
			return (boolean)$result;
		}
		
		/*
		 *	Change the mode of file
		 *
		 *	@param	string	Path to file
		 *	@param	int		Mode (octal)
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function chmod($file, $mode)
		{
			return (boolean)chmod($file, $mode);
		}
		
		/*
		 *	Change owner of file
		 *
		 *	@param	string	Path to file
		 *	@param	string	Username
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function chown($file, $user)
		{
			return (boolean)chown($file, $user);
		}
		
		/*
		 *	Copy file
		 *
		 *	@param	string	Path to file
		 *	@param	string	New path for copy of file
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function copy($file, $dest)
		{
			if(self::exists($dest))
			{
				\Nano\Debug::write(__METHOD__.': "'.$file.'" will be overwritten');
			}
			
			return (boolean)copy($file, $dest);
		}
		
		/*
		 *	Alias to "self::unlink()"
		 */
		static public function delete($file)
		{
			return self::unlink($file);
		}
		
		/*
		 *	Checks whether a file or directory exists.
		 *
		 * 	@param	string	Path to file or directory
		 *	@return string
		 *	@return	false	On failre	
		 * 
		 *	@static
		 */
		static public function exists($file)
		{
			return (boolean)file_exists($file);
		}
		
		/*
		 *	Get contents of file in string
		 *
		 *	@param	string	Path to file
		 *	@param	boolean	Trim contents?
		 *	@return	mixed
		 *
		 *	@static
		 */
		static public function get($file, $trim = false)
		{
			$contents = file_get_contents($file);
			
			if($trim)
			{
				return trim($contents);
			}
			else
			{
				return $contents;
			}
		}
		
		/*
		 *	Put contents into a file
		 *
		 *	@param	string	Path to file
		 *	@param	string	Data to write
		 *	@param	string	Type of writing (overwrite or append) [optional]
		 *	@param	boolean	Lock the file after writeing? [optional]
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function put($file, $contents, $type = 'overwrite', $lock = false)
		{
			switch($type)
			{
				case 'overwrite':
				{
					if($lock)
					{
						return (boolean)file_put_contents($file, $contents, LOCK_EX);
					}
					else
					{
						return (boolean)file_put_contents($file, $contents);
					}
				}
				
				case 'append':
				{
					if($lock)
					{
						return (boolean)file_put_contents($file, $contents, FILE_APPEND | LOCK_EX);
					}
					else
					{
						return (boolean)file_put_contents($file, $contents, FILE_APPEND);
					}
				}
			}
		}
		
		/*
		 *	Get contents of file in array
		 *
		 *	@param	string	Path to file
		 *	@param	boolean	Skip empty lines?
		 *	@return	array
		 *
		 *	@static
		 */
		static public function file($file, $emptyl = true)
		{
			if(!$emptyl)
			{
				return file($file, FILE_SKIP_EMPTY_LINES);
			}
			else
			{
				return file($file);
			}
		}
		
		/*
		 *	Get type of path
		 *
		 *	@param	string	Path to file or directory
		 *	@return	string
		 *
		 *	@static
		 */
		static public function type($file)
		{
			return (string)filetype($file);
		}
		
		/*
		 *	Get size of path
		 *
		 *	@param	string	Path to file or directory
		 *	@return	int		File size in bytes
		 *
		 *	@static
		 */
		static public function size($file)
		{
			return (int)filesize($file);
		}
		
		/*
		 *	Move uploaded file to some dir
		 *
		 *	@param	string	Filename
		 *	@param	string	Move to ...
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function move($file, $to)
		{
			if(self::is('uploaded', $file))
			{
				return (boolean)(move_uploaded_file($file, $to) && self::chmod($to, 0777));
			}
			else
			{
				return (boolean)(self::copy($file, $to) && self::unlink($file));
			}
		}
		
		/*
		 *	Create symlink of file or folder
		 *
		 *	@param	string	Target file
		 *	@param	string	Symlink
		 *
		 *	@return	boolean
		 */
		static public function symlink($target, $link)
		{
			return (boolean)symlink($target, $link);
		}
		
		/*
		 *	Return mime type of a file
		 *
		 *	@param	string	Path to file
		 *	@return	string
		 *
		 *	@static
		 */
		 static public function mime($file)
		 {
			$finfo = finfo_open(FILEINFO_MIME);
			
			$type = finfo_file($finfo, $file);
			
			finfo_close($finfo);
			
			return $type;
		 }
		 
		 /*
		  *	Read file
		  *
		  *	@param	string	Path to file
		  *	@return	string
		  *
		  *	@static
		  */
		 static public function read($file)
		 {
			return readfile($file);
		 }
		
		/*
		 *	Get type of path
		 *
		 *	@param	string	Type
		 *	@param	string	Path
		 *	@return	boolean
		 *
		 *	@static
		 */
		static public function is($type, $path)
		{
			switch($type)
			{
				case 'dir':
				{
					return (boolean)is_dir($path);	
				}
				
				case 'executable':
				{
					return (boolean)is_executable($path);
				}
				
				case 'file':
				{
					return (boolean)is_file($path);
				}
				
				case 'link':
				{
					return (boolean)is_link($path);
				}
				
				case 'readable':
				{
					return (boolean)is_readable($path);
				}
				
				case 'uploaded':
				{
					return (boolean)is_uploaded_file($path);
				}
				
				case 'writable':
				case 'writeable':
				{
					return (boolean)is_writable($path);
				}
				
				case 'image':
				{
					switch(self::mime($path))
					{
						case 'image/png':
						case 'image/jpeg':
						case 'image/jpeg':
						case 'image/jpeg':
						case 'image/gif':
						case 'image/bmp':
						case 'image/vnd.microsoft.icon':
						case 'image/tiff':
						case 'image/tiff':
						case 'image/svg+xml':
						case 'image/svg+xml':
						{
							return true;	
						}
					}
					
					return false;
				}
				
				case 'archive':
				{
					switch(self::mime($path))
					{
						case 'application/zip':
						case 'application/x-rar-compressed':
						case 'application/x-msdownload':
						case 'application/x-msdownload':
						case 'application/vnd.ms-cab-compressed':
						{
							return true;	
						}
					}
					
					return false;
				}
			}
		}
	}
}